/**
 * Copyright © 2017-2018 Beijing Audiotone Technology Co.,Ltd.
 * All Rights Reserved.
 * This software is the confidential and proprietary information of
 * Beijing Audiotone Technology Co.,Ltd.
 * ("Confidential Information"). You shall not disclose such
 * Confidential Information and shall use it only in accordance with
 * the terms of the license agreement you entered into with Audiotone.
 * AUDIOTONE MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
 * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. AUDIOTONE SHALL NOT BE LIABLE FOR
 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 */
package pro.uccs.util;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;

/****************************************************************
 * Copyright © 2017,北京世纪奥通科技有限公司
 * All Rights Reserved.
 * 文件名称： Coder.java
 * 摘    要： [简要描述本文件的内容]
 * 初始版本： 1.0.0
 * 原 作 者： songchen
 * 完成日期： 2018年07月10日 14时59分
 * 当前版本： 1.0.0
 * 作    者： songchen
 * 完成日期： 2018年07月10日 14时59分
 *
 *****************************************************************/
public abstract class Coder {
    public static final String KEY_SHA = "SHA";
    public static final String KEY_MD5 = "md5";
    public static final String KEY_MAC = "HmacMD5";
    public static final int MD5_ENCRYPT_LEN = 32;
    public static final int MD5_HEXDIGITS = 15;
    public static final int MD5_HEXDIGITS_LOOP = 4;
    public static final int MD5_HEXDIGITS_FLOOP = 16;

    public Coder() {
    }

    public static byte[] decryptBASE64(String key) throws Exception {
        return Base64.decodeBase64(key);
    }

    public static String encryptBASE64(byte[] key) throws Exception {
        return Base64.encodeBase64String(key);
    }

    public static byte[] encryptMD5(byte[] data) throws Exception {
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        md5.update(data);
        return md5.digest();
    }

    public static String encryptMD5(String data) throws Exception {
        if (data != null && data.trim().length() != 0) {
            String md5Str = "";
            byte[] md5byte = encryptMD5(data.getBytes());
            char[] hexDigits = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
            char[] str = new char[32];
            int k = 0;

            for(int i = 0; i < 16; ++i) {
                byte byte0 = md5byte[i];
                str[k++] = hexDigits[byte0 >>> 4 & 15];
                str[k++] = hexDigits[byte0 & 15];
            }

            md5Str = new String(str);
            return md5Str;
        } else {
            throw new IllegalArgumentException("密码参数不能为空");
        }
    }

    public static byte[] encryptSHA(byte[] data) throws Exception {
        MessageDigest sha = MessageDigest.getInstance("SHA");
        sha.update(data);
        return sha.digest();
    }

    public static String initMacKey() throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5");
        SecretKey secretKey = keyGenerator.generateKey();
        return encryptBASE64(secretKey.getEncoded());
    }

    public static byte[] encryptHMAC(byte[] data, String key) throws Exception {
        SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), "HmacMD5");
        Mac mac = Mac.getInstance(secretKey.getAlgorithm());
        mac.init(secretKey);
        return mac.doFinal(data);
    }
}
